from django import forms
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db import models
from modelcluster.fields import ParentalManyToManyField
from wagtail.admin.panels import FieldPanel, MultiFieldPanel
from wagtail.fields import StreamField
from wagtail.models import DraftStateMixin, Page, RevisionMixin
from wagtail.search import index
from wagtail.snippets.models import register_snippet

from portal.blocks import BaseStreamBlock


@register_snippet
class Country(models.Model):
    title = models.CharField(max_length=100)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = "产地"


@register_snippet
class ProductIngredient(DraftStateMixin, RevisionMixin, models.Model):

    name = models.CharField(max_length=255)

    panels = [
        FieldPanel("name"),
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "其它"


@register_snippet
class ProductType(RevisionMixin, models.Model):

    title = models.CharField(max_length=255)

    panels = [
        FieldPanel("title"),
    ]

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = "产品种类"


class ProductPage(Page):
    introduction = models.TextField(help_text="页面文字描述", blank=True,verbose_name="文字描述")
    image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text="仅限横向模式；水平宽度介于1000px和3000px之间。",
        verbose_name="图片"
    )
    body = StreamField(
        BaseStreamBlock(), verbose_name="正文内容", blank=True, use_json_field=True
    )
    origin = models.ForeignKey(
        Country,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name="产地"
    )

    product_type = models.ForeignKey(
        "product.ProductType",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="产品种类"
    )
    ingredients = ParentalManyToManyField("ProductIngredient", blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("introduction"),
        FieldPanel("image"),
        FieldPanel("body"),
        FieldPanel("origin"),
        FieldPanel("product_type"),
        MultiFieldPanel(
            [
                FieldPanel(
                    "ingredients",
                    widget=forms.CheckboxSelectMultiple,
                ),
            ],
            heading="其它",
            # classname="collapsed",
        ),
    ]

    search_fields = Page.search_fields + [
        index.SearchField("body"),
    ]

    parent_page_types = ["ProductIndexPage"]


class ProductIndexPage(Page):
    introduction = models.TextField(help_text="页面文字描述", blank=True, verbose_name="页面描述")
    image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text="仅限横向模式；水平宽度介于1000px和3000px之间。",
        verbose_name="图片"
    )

    content_panels = Page.content_panels + [
        FieldPanel("introduction"),
        FieldPanel("image"),
    ]

    subpage_types = ["ProductPage"]

    def get_product(self):
        return (
            ProductPage.objects.live().descendant_of(self).order_by("-first_published_at")
        )

    def children(self):
        return self.get_children().specific().live()

    def paginate(self, request, *args):
        page = request.GET.get("page")
        paginator = Paginator(self.get_product(), 8)
        try:
            pages = paginator.page(page)
        except PageNotAnInteger:
            pages = paginator.page(1)
        except EmptyPage:
            pages = paginator.page(paginator.num_pages)
        return pages

    def get_context(self, request):
        context = super(ProductIndexPage, self).get_context(request)

        # ProductPage objects (get_product) are passed through pagination
        product = self.paginate(request, self.get_product())

        context["product"] = product

        return context
